package interfaceAPI

/*
   #cgo CFLAGS: -I../
   #cgo LDFLAGS: -L../ -ldecd -lm
	#include "compute.h"
	#include "device.h"
	#include "key.h"
	#include "manager.h"
	#include "xdma.h"
   #include <stdlib.h>
*/
import "C"
import (
	"bufio"
	"bytes"
	"encoding/binary"
	"encoding/hex"
	"errors"
	"fmt"
	"os"
	"reflect"

	"gitee.com/fhe-search/nfhedecd/denseComputiing"
)

// 判断文件是否存在
func FileYesOrNot(fileName string) bool {
	f, err := os.Open(fileName)
	if err != nil && os.IsNotExist(err) {
		return false
	}
	defer f.Close()
	return true
}

//// 将密钥写入字节文件
//func FileWriteKeyByte(fileName string, encKeyByte []byte) error {
//	var errMsg error
//	fileObj, errMsg := os.OpenFile(fileName, os.O_RDWR | os.O_TRUNC, 0644) // 打开密钥文件
//	defer fileObj.Close()
//	if errMsg != nil {
//		errMsg = errors.New("打开文件失败？")
//	} else {
//		fileObj.Write(encKeyByte) // 将密钥写入文件
//	}
//	return errMsg
//}
//
//// 读密钥字节文件
//func FileReadKeyByte(fileName string) ([]byte, error) {
//	var errmsg error
//	var readByte [] byte = make([]byte, 1024)
//	fileObj, errmsg := os.OpenFile(fileName, os.O_RDWR, 0644)
//	if errmsg != nil {
//		errmsg = errors.New("打开文件失败?")
//	} else {
//		fileObj.ReadAt(readByte,0)
//	}
//	return readByte, errmsg
//}

// 将密钥写入字节文件
func FileWriteKeyByte(fileName string, encKeyByte []byte) error {
	var errMsg error
	fileObj, errMsg := os.OpenFile(fileName, os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0666) // 打开密钥文件
	defer fileObj.Close()
	if errMsg != nil {
		errMsg = errors.New("打开文件失败？")
	} else {
		writer := bufio.NewWriter(fileObj)
		str := hex.EncodeToString(encKeyByte) // + "\n"
		writer.WriteString(str)               // 将密钥写入文件
		writer.Flush()
		//fileObj.Write(encKeyByte) // 将密钥写入文件
	}
	return errMsg
}

// 读密钥字节文件
func FileReadKeyByte(fileName string) ([]byte, error) {
	var errmsg error
	var readByte []byte = make([]byte, 1024)
	fileObj, errmsg := os.Open(fileName)
	if errmsg != nil {
		errmsg = errors.New("打开文件失败?")
	} else {
		reader := bufio.NewReader(fileObj)
		str, _ := reader.ReadString('\n')
		if len(str) > 0 {
			readByte, _ = hex.DecodeString(str)
		} else {
			fmt.Println("密钥文件内容错误？")
		}
		//fileObj.ReadAt(readByte,0)
	}
	return readByte, errmsg
}

// 从文件中获取用户权限口令
func ExportUserAuthPW(keyIndex uint) string {
	s := fmt.Sprintf("%d", keyIndex)
	Ls_File_Name := "./UAP/08_NFHE_DECD_Auth"
	Ls_File_Name += s
	Ls_File_Name = Ls_File_Name + ".txt"
	var Auth_value []byte
	var retAuthPW string
	Auth_value, errMsg := FileReadKeyByte(Ls_File_Name)
	if errMsg == nil {
		retAuthPW = hex.EncodeToString(Auth_value)
		//fmt.Println(errMsg, "获取用户权限口令成功！"+"/", Auth_value)
	} else {
		fmt.Println(errMsg)
	}
	return retAuthPW
}

// 从文件中获取用户权限口令
func ExportUserAuthPWPrefix(keyIndex uint64, prefix string) string {
	s := fmt.Sprintf("%d", keyIndex)
	Ls_File_Name := "./UAP/08_NFHE_DECD_Auth"
	Ls_File_Name += s
	Ls_File_Name = Ls_File_Name + ".txt"
	var Auth_value []byte
	var retAuthPW string
	Auth_value, errMsg := FileReadKeyByte(prefix + Ls_File_Name)
	if errMsg == nil {
		retAuthPW = hex.EncodeToString(Auth_value)
		//fmt.Println(errMsg, "获取用户权限口令成功！"+"/", Auth_value)
	} else {
		fmt.Println(errMsg)
	}
	return retAuthPW
}

// 打印一批解密的结果明文
func PrintPlainResultEx(nCount uint, plainResult []byte, plainResultType []byte, messagex string) {
	countFirt := 0 // 记录一批数据第一个位置
	countEnd := 0  // 记录一批数据第二个位置
	for i := 0; i < int(nCount); i++ {
		choice := plainResultType[i] // 得到第一个明文结果数据类型
		switch choice {
		case 0: //"uint32": // 32位无符号整数
			var PlainDataBytevalueTmp []byte
			var plainDatavalue uint32 // 说明解密后的明文数据类型的变量
			PlainDataBytevalueTmp = plainResult[countFirt+4 : countEnd+8]
			plainDatavalue = BytesToUint32(PlainDataBytevalueTmp) // 将字节转换为对应的数据类型值
			//var plainDatavalue uint64 // 说明解密后的明文数据类型的变量
			//PlainDataBytevalueTmp = plainResult[countFirt : countEnd+8]
			//plainDatavalue = BytesToUint64(PlainDataBytevalueTmp) // 将字节转换为对应的数据类型值
			fmt.Println(messagex+"解密的第", i+1, "个明文", plainDatavalue)
		case 1: //"int32", "int": // 32位有符号整数
			var PlainDataBytevalueTmp []byte
			var plainDatavalue int32 // 说明解密后的明文数据类型的变量
			PlainDataBytevalueTmp = plainResult[countFirt+4 : countEnd+8]
			plainDatavalue = BytesToInt32(PlainDataBytevalueTmp) // 将字节转换为对应的数据类型值
			fmt.Println(messagex+"解密的第", i+1, "个明文", plainDatavalue)
		case 2: //"uint64": // 64位无符号整数
			var PlainDataBytevalueTmp []byte
			var plainDatavalue uint64 // 说明解密后的明文数据类型的变量
			PlainDataBytevalueTmp = plainResult[countFirt+0 : countEnd+8]
			plainDatavalue = BytesToUint64(PlainDataBytevalueTmp) // 将字节转换为对应的数据类型值
			fmt.Println(messagex+"解密的第", i+1, "个明文", plainDatavalue)
		case 3: //"int64": // 64位有符号整数
			var PlainDataBytevalueTmp []byte
			var plainDatavalue int64 // 说明解密后的明文数据类型的变量
			PlainDataBytevalueTmp = plainResult[countFirt+0 : countEnd+8]
			plainDatavalue = BytesToInt64(PlainDataBytevalueTmp) // 将字节转换为对应的数据类型值
			fmt.Println(messagex+"解密的第", i+1, "个明文", plainDatavalue)
		case 4: //"float32": // 32位浮点数
			var PlainDataBytevalueTmp []byte
			var plainDatavalue float32 // 说明解密后的明文数据类型的变量
			PlainDataBytevalueTmp = plainResult[countFirt+4 : countEnd+8]
			plainDatavalue = BytesToFloat32(PlainDataBytevalueTmp) // 将字节转换为对应的数据类型值
			fmt.Println(messagex+"解密的第", i+1, "个明文", plainDatavalue)
		case 5: //"float64": // 64位浮点数
			var PlainDataBytevalueTmp []byte
			var plainDatavalue float64 // 说明解密后的明文数据类型的变量
			PlainDataBytevalueTmp = plainResult[countFirt+0 : countEnd+8]
			plainDatavalue = BytesToFloat64(PlainDataBytevalueTmp) // 将字节转换为对应的数据类型值
			fmt.Println(messagex+"解密的第", i+1, "个明文", plainDatavalue)
		default:
			errMsg := errors.New("密文数据类型不对？")
			fmt.Println(errMsg)
		}
		countFirt += 8 // 修改位置
		countEnd += 8
	}
}

// 打印一批解密的关系运算结果明文
func PrintPlainRelationResultEx(nCount uint, plainResult []byte, plainResultType []byte, messagex string) ([]int32, error) {
	var retPlainResult []int32
	countFirt := 0 // 记录一批数据第一个位置
	//countEnd := 4  // 记录一批数据第二个位置
	retPlainResult = make([]int32, nCount)
	for i := 0; i < int(nCount); i++ {
		choice := plainResultType[i] // 得到第一个明文结果数据类型
		switch choice {
		case 0: //"uint32": // 32位无符号整数
			var PlainDataBytevalueTmp []byte
			var plainDatavalue uint32 // 说明解密后的明文数据类型的变量

			PlainDataBytevalueTmp = plainResult[countFirt+7 : countFirt+8]
			plainDatavalue = uint32(PlainDataBytevalueTmp[0]) // 将字节转换为对应的数据类型值
			fmt.Println(messagex+"解密的第", i+1, "个明文", plainDatavalue)
			retPlainResult[i] = int32(plainDatavalue)
		case 1: //"int32", "int": // 32位有符号整数
			var PlainDataBytevalueTmp []byte
			var plainDatavalue int32 // 说明解密后的明文数据类型的变量

			PlainDataBytevalueTmp = plainResult[countFirt+7 : countFirt+8]
			plainDatavalue = int32(PlainDataBytevalueTmp[0]) // 将字节转换为对应的数据类型值
			fmt.Println("解密的第", i+1, "个明文", plainDatavalue)
		//case 2: //"uint64": // 64位无符号整数
		//	var PlainDataBytevalueTmp, PlainDataBytevalueTmp1 []byte
		//	var plainDatavalue, plainDatavalue1 uint64 // 说明解密后的明文数据类型的变量
		//
		//	PlainDataBytevalueTmp = plainResult[countFirt+0 : countEnd+8]
		//	plainDatavalue = BytesToUint64(PlainDataBytevalueTmp) // 将字节转换为对应的数据类型值
		//
		//	PlainDataBytevalueTmp1 = plainResult[countFirt+8 : countEnd+8]
		//	plainDatavalue1 = BytesToUint64(PlainDataBytevalueTmp1) // 将字节转换为对应的数据类型值
		//	fmt.Println("解密的第", i+1, "个明文", plainDatavalue, plainDatavalue1)
		//case 3: //"int64": // 64位有符号整数
		//	var PlainDataBytevalueTmp, PlainDataBytevalueTmp1 []byte
		//	var plainDatavalue, plainDatavalue1 int64 // 说明解密后的明文数据类型的变量
		//
		//	PlainDataBytevalueTmp = plainResult[countFirt+8 : countEnd+8]
		//	plainDatavalue = BytesToInt64(PlainDataBytevalueTmp) // 将字节转换为对应的数据类型值
		//
		//	PlainDataBytevalueTmp1 = plainResult[countFirt+8 : countEnd+8]
		//	plainDatavalue1 = BytesToInt64(PlainDataBytevalueTmp1) // 将字节转换为对应的数据类型值
		//	fmt.Println("解密的第", i+1, "个明文", plainDatavalue, plainDatavalue1)
		//case 4: //"float32": // 32位浮点数
		//	var PlainDataBytevalueTmp, PlainDataBytevalueTmp1 []byte
		//	var plainDatavalue, plainDatavalue1 float32 // 说明解密后的明文数据类型的变量
		//
		//	PlainDataBytevalueTmp = plainResult[countFirt+8 : countEnd+8]
		//	plainDatavalue = BytesToFloat32(PlainDataBytevalueTmp) // 将字节转换为对应的数据类型值
		//
		//	PlainDataBytevalueTmp1 = plainResult[countFirt+8 : countEnd+8]
		//	plainDatavalue1 = BytesToFloat32(PlainDataBytevalueTmp1) // 将字节转换为对应的数据类型值
		//	fmt.Println("解密的第", i+1, "个明文", plainDatavalue, plainDatavalue1)
		//case 5: //"float64": // 64位浮点数
		//	var PlainDataBytevalueTmp, PlainDataBytevalueTmp1 []byte
		//	var plainDatavalue, plainDatavalue1 float64 // 说明解密后的明文数据类型的变量
		//
		//	PlainDataBytevalueTmp = plainResult[countFirt+8 : countEnd+8]
		//	plainDatavalue = BytesToFloat64(PlainDataBytevalueTmp) // 将字节转换为对应的数据类型值
		//
		//	PlainDataBytevalueTmp1 = plainResult[countFirt+8 : countEnd+8]
		//	plainDatavalue1 = BytesToFloat64(PlainDataBytevalueTmp1) // 将字节转换为对应的数据类型值
		//	fmt.Println("解密的第", i+1, "个明文", plainDatavalue, plainDatavalue1)
		default:
			errMsg := errors.New("密文数据类型不对？")
			fmt.Println(errMsg)
		}
		countFirt += 8 // 修改位置
		//countEnd += 16
	}
	return retPlainResult, nil
}

// 拟用浮点数返回一批解密的结果明文
func PlainResultEx(nCount uint, plainResult []byte, plainResultType []byte) []float64 {
	var PlainResultEx []float64
	PlainResultEx = make([]float64, nCount)
	countFirt := 0 // 记录一批数据第一个位置
	countEnd := 0  // 记录一批数据第二个位置
	for i := 0; i < int(nCount); i++ {
		choice := plainResultType[i] // 得到第一个明文结果数据类型
		switch choice {
		case 0: //"uint32": // 32位无符号整数
			var PlainDataBytevalueTmp []byte
			var plainDatavalue uint32 // 说明解密后的明文数据类型的变量
			PlainDataBytevalueTmp = plainResult[countFirt+4 : countEnd+8]
			plainDatavalue = BytesToUint32(PlainDataBytevalueTmp) // 将字节转换为对应的数据类型值
			PlainResultEx[i] = float64((plainDatavalue))
		case 1: //"int32", "int": // 32位有符号整数
			var PlainDataBytevalueTmp []byte
			var plainDatavalue int32 // 说明解密后的明文数据类型的变量
			PlainDataBytevalueTmp = plainResult[countFirt+4 : countEnd+8]
			plainDatavalue = BytesToInt32(PlainDataBytevalueTmp) // 将字节转换为对应的数据类型值
			PlainResultEx[i] = float64((plainDatavalue))
		case 2: //"uint64": // 64位无符号整数
			var PlainDataBytevalueTmp []byte
			var plainDatavalue uint64 // 说明解密后的明文数据类型的变量
			PlainDataBytevalueTmp = plainResult[countFirt+0 : countEnd+8]
			plainDatavalue = BytesToUint64(PlainDataBytevalueTmp) // 将字节转换为对应的数据类型值
			PlainResultEx[i] = float64((plainDatavalue))
		case 3: //"int64": // 64位有符号整数
			var PlainDataBytevalueTmp []byte
			var plainDatavalue int64 // 说明解密后的明文数据类型的变量
			PlainDataBytevalueTmp = plainResult[countFirt+0 : countEnd+8]
			plainDatavalue = BytesToInt64(PlainDataBytevalueTmp) // 将字节转换为对应的数据类型值
			PlainResultEx[i] = float64((plainDatavalue))
		case 4: //"float32": // 32位浮点数
			var PlainDataBytevalueTmp []byte
			var plainDatavalue float32 // 说明解密后的明文数据类型的变量
			PlainDataBytevalueTmp = plainResult[countFirt+4 : countEnd+8]
			plainDatavalue = BytesToFloat32(PlainDataBytevalueTmp) // 将字节转换为对应的数据类型值
			PlainResultEx[i] = float64((plainDatavalue))
		case 5: //"float64": // 64位浮点数
			var PlainDataBytevalueTmp []byte
			var plainDatavalue float64 // 说明解密后的明文数据类型的变量
			PlainDataBytevalueTmp = plainResult[countFirt+0 : countEnd+8]
			plainDatavalue = BytesToFloat64(PlainDataBytevalueTmp) // 将字节转换为对应的数据类型值
			PlainResultEx[i] = float64((plainDatavalue))
		default:
			errMsg := errors.New("解密的明文数据类型不符？")
			fmt.Println(errMsg)
		}
		countFirt += 8 // 修改位置
		countEnd += 8
	}
	return PlainResultEx
}

// 打印解密结果
func PrintplainData(plainDataValue interface{}) float64 {
	var PlainData float64
	//fmt.Println("打印解密的明文：", plainDataValue)
	switch plainDataValue.(type) {
	case int32, int: // 32位有符号整数
		//var plainDataTmp1 int32
		//plainDataTmp := reflect.ValueOf(plainDataValue)
		//plainDataTmp1 = int32(plainDataTmp.Int())
		var plainDataTmp1 int64
		plainDataTmp := reflect.ValueOf(plainDataValue)
		plainDataTmp1 = int64(plainDataTmp.Int())
		fmt.Println("解密int的明文：", plainDataTmp1)
		PlainData = float64(plainDataTmp1) //临时统一转换为64位浮点数
	case uint32: // 32位无符号整数
		var plainDataTmp1 uint32
		plainDataTmp := reflect.ValueOf(plainDataValue)
		plainDataTmp1 = uint32(plainDataTmp.Uint())
		fmt.Println("解密uint的明文：", plainDataTmp1)
		PlainData = float64(plainDataTmp1) //临时统一转换为64位浮点数
	case int64: // 64位有符号整数
		var plainDataTmp1 int64
		plainDataTmp := reflect.ValueOf(plainDataValue)
		plainDataTmp1 = int64(plainDataTmp.Int())
		fmt.Println("解密int64的明文：", plainDataTmp1)
		PlainData = float64(plainDataTmp1) //临时统一转换为64位浮点数
	case uint64: // 64位无符号整数
		var plainDataTmp1 uint64
		plainDataTmp := reflect.ValueOf(plainDataValue)
		plainDataTmp1 = uint64(plainDataTmp.Uint())
		fmt.Println("解密uint64的明文：", plainDataTmp1)
		PlainData = float64(plainDataTmp1) //临时统一转换为64位浮点数
	case float32: // 32位浮点数
		var plainDataTmp1 float32
		plainDataTmp := reflect.ValueOf(plainDataValue)
		plainDataTmp1 = float32(plainDataTmp.Float())
		fmt.Println("解密float32的明文：", plainDataTmp1)
		PlainData = float64(plainDataTmp1) //临时统一转换为64位浮点数
	case float64: // 64位浮点数
		var plainDataTmp1 float64
		plainDataTmp := reflect.ValueOf(plainDataValue)
		plainDataTmp1 = float64(plainDataTmp.Float())
		fmt.Println("解密float64的明文：", plainDataTmp1)
		PlainData = float64(plainDataTmp1) //临时统一转换为64位浮点数
	default:
		fmt.Println("解密明文的数据类型不符？")
	}
	return PlainData
}

// -----------------批处理----------------加密
// 将一批明文加密成密文

func EncEx(uiKeyIndex []uint, nCount uint, plainData []interface{}) ([]byte, error) {
	var errMsg error     // 出错返回值
	var RetEncStr []byte // 功能返回密文值
	var tmp reflect.Value
	switch plainData[0].(type) {
	case int32, int: // 32位有符号整数
		plainDataTmp1 := make([]int32, nCount)
		for i := uint(0); i < nCount; i++ {
			var pd = plainData[i]
			tmp = reflect.ValueOf(pd)
			plainDataTmp1[i] = int32(tmp.Int())
		}
		//Please notice parameter
		keyIndexTmp := make([]uint, nCount)
		for j := uint(0); j < nCount; j++ {
			keyIndexTmp[j] = uiKeyIndex[j]
		}
		RetEncStr, errMsg = denseComputiing.PEncS32Ex(keyIndexTmp, nCount, plainDataTmp1)
		if errMsg == nil {
			return RetEncStr, errMsg
		}
	case uint32: // 32位无符号整数
		plainDataTmp1 := make([]uint, nCount)
		for i := uint(0); i < nCount; i++ {
			var pd = plainData[i]
			tmp = reflect.ValueOf(pd)
			plainDataTmp1[i] = uint(tmp.Int())
		}
		keyIndexTmp := make([]uint, nCount)
		for j := uint(0); j < nCount; j++ {
			keyIndexTmp[j] = uiKeyIndex[j]
		}

		RetEncStr, errMsg := denseComputiing.PEnc32Ex(keyIndexTmp, uint(nCount), plainDataTmp1)
		if errMsg == nil {
			return RetEncStr, errMsg
		}
	case uint64: // 64位有符号整数
		plainDataTmp1 := make([]uint64, nCount)
		for i := uint(0); i < nCount; i++ {
			var pd = plainData[i]
			tmp = reflect.ValueOf(pd)
			plainDataTmp1[i] = uint64(tmp.Int())
		}
		keyIndexTmp := make([]uint, nCount)
		for j := uint(0); j < nCount; j++ {
			keyIndexTmp[j] = uiKeyIndex[j]
		}
		RetEncStr, errMsg := denseComputiing.PEncS64Ex(keyIndexTmp, uint(nCount), plainDataTmp1)
		if errMsg == nil {
			return RetEncStr, errMsg
		}
	case int64: // 64位无符号整数
		plainDataTmp1 := make([]int64, nCount)
		for i := uint(0); i < nCount; i++ {
			var pd = plainData[i]
			tmp = reflect.ValueOf(pd)
			plainDataTmp1[i] = int64(tmp.Int())
		}
		keyIndexTmp := make([]uint, nCount)
		for j := uint(0); j < nCount; j++ {
			keyIndexTmp[j] = uiKeyIndex[j]
		}
		RetEncStr, errMsg := denseComputiing.PEnc64Ex(keyIndexTmp, uint(nCount), plainDataTmp1)
		if errMsg == nil {
			return RetEncStr, errMsg
		}
	case float32: // 32位浮点数
		plainDataTmp1 := make([]float32, nCount)
		for i := uint(0); i < nCount; i++ {
			var pd = plainData[i]
			tmp = reflect.ValueOf(pd)
			plainDataTmp1[i] = float32(tmp.Float())
		}
		keyIndexTmp := make([]uint, nCount)
		for j := uint(0); j < nCount; j++ {
			keyIndexTmp[j] = uiKeyIndex[j]
		}
		RetEncStr, errMsg := denseComputiing.PEncF32Ex(keyIndexTmp, uint(nCount), plainDataTmp1)
		if errMsg == nil {
			return RetEncStr, errMsg
		}
	case float64: // 64位浮点数
		plainDataTmp1 := make([]float64, nCount)
		for i := uint(0); i < nCount; i++ {
			var pd = plainData[i]
			tmp = reflect.ValueOf(pd)
			plainDataTmp1[i] = float64(tmp.Float())
		}
		keyIndexTmp := make([]uint, nCount)
		for j := uint(0); j < nCount; j++ {
			keyIndexTmp[j] = uiKeyIndex[j]
		}
		RetEncStr, errMsg := denseComputiing.PEncF64Ex(keyIndexTmp, uint(nCount), plainDataTmp1)
		if errMsg == nil {
			return RetEncStr, errMsg
		}
	default:
		errMsg = errors.New("明文的数据类型不符？")
	}
	return RetEncStr, errMsg
}

// -----------------批处理----------------解密
// 将一批密文解密成明文

func DecEx(uiKeyIndex []uint, nCount uint, encData []byte, userAuthPW string) ([]byte, []byte, error) {
	var err error                                                                                       // 出错返回值
	plainDataBytevalue, plainType, _ := denseComputiing.PDecEx(uiKeyIndex, nCount, encData, userAuthPW) //调用解密函数接口
	//fmt.Println(plainDataBytevalue, plainDataBytevalue)
	return plainDataBytevalue, plainType, err
}

// -----------------------------------------加密
// 将明文加密成密文
func Enc(uiKeyIndex uint, plainData interface{}) ([]byte, error) {
	var errMsg error     // 出错返回值
	var RetEncStr []byte // 功能返回密文值
	switch plainData.(type) {
	case int32, int: // 32位有符号整数
		var plainDataTmp1 int32
		plainDataTmp := reflect.ValueOf(plainData)
		plainDataTmp1 = int32(plainDataTmp.Int())
		RetEncStr, errMsg = denseComputiing.PEncS32(uiKeyIndex, plainDataTmp1)
		if errMsg == nil {
			return RetEncStr, errMsg
		} else {
			fmt.Println(errMsg)
		}
	case uint32: // 32位无符号整数
		var plainDataTmp2 uint32
		plainDataTmp := reflect.ValueOf(plainData)
		plainDataTmp2 = uint32(plainDataTmp.Uint())
		RetEncStr, errMsg := denseComputiing.PEnc32(uiKeyIndex, plainDataTmp2)
		if errMsg == nil {
			return RetEncStr, errMsg
		}
	case int64: // 64位有符号整数
		var plainDataTmp3 int64
		plainDataTmp := reflect.ValueOf(plainData)
		plainDataTmp3 = int64(plainDataTmp.Int())
		RetEncStr, errMsg := denseComputiing.PEncS64(uiKeyIndex, plainDataTmp3)
		if errMsg == nil {
			return RetEncStr, errMsg
		}
	case uint64: // 64位无符号整数
		var plainDataTmp4 uint64
		plainDataTmp := reflect.ValueOf(plainData)
		plainDataTmp4 = uint64(plainDataTmp.Uint())
		RetEncStr, errMsg := denseComputiing.PEnc64(uiKeyIndex, plainDataTmp4)
		if errMsg == nil {
			return RetEncStr, errMsg
		}
	case float32: // 32位浮点数
		var plainDataTmp5 float32
		plainDataTmp := reflect.ValueOf(plainData)
		plainDataTmp5 = float32(plainDataTmp.Float())
		RetEncStr, errMsg := denseComputiing.PEncF32(uiKeyIndex, plainDataTmp5)
		if errMsg == nil {
			return RetEncStr, errMsg
		}
	case float64: // 64位浮点数
		var plainDataTmp6 float64
		plainDataTmp := reflect.ValueOf(plainData)
		plainDataTmp6 = float64(plainDataTmp.Float())
		RetEncStr, errMsg := denseComputiing.PEncF64(uiKeyIndex, plainDataTmp6)
		if errMsg == nil {
			return RetEncStr, errMsg
		}
	default:
		errMsg = errors.New("明文的数据类型不符？")
	}
	return RetEncStr, errMsg
}

// -----------------------------------------解密
// 将密文解密成明文
func Dec(uiKeyIndex uint, encData []byte, userAuthPW string) (interface{}, error) {
	var errMsg error                                                                          // 出错返回值
	plainDataBytevalue, plainType, _ := denseComputiing.PDec(uiKeyIndex, encData, userAuthPW) //调用解密函数接口
	choice := plainType                                                                       //BytesToInt32(plainType)                                                         // 得到数据类型
	// 根据plainType值调用对应的数据类型转换函数
	var plainDataInterface interface{} // 说明返回结果的interface变量
	//fmt.Println("获得解密的数据类型：", choice)
	switch choice {
	case 0: //"int32", "int": // 32位有符号整数
		var plainDatavalue int32                               // 说明解密后的明文数据类型的变量
		plainDatavalue = BytesToInt32(plainDataBytevalue[4:8]) // 将字节转换为对应的数据类型值
		plainDataInterface = plainDatavalue                    // 将明文结果值复制给接口
		return plainDataInterface, errMsg
		//plainDataTmp, errMsg := denseComputiing.PDecS32(encData, userAuthPW)
	case 1: //"uint32": // 32位无符号整数
		var plainDatavalue uint32                               // 说明解密后的明文数据类型的变量
		plainDatavalue = BytesToUint32(plainDataBytevalue[4:8]) // 将字节转换为对应的数据类型值
		plainDataInterface = plainDatavalue                     // 将明文结果值复制给接口
		return plainDataInterface, errMsg
		//plainDataTmp, errMsg := denseComputiing.PDec32(encData, userAuthPW)
	case 2: //"int64": // 64位有符号整数
		var plainDatavalue int64                               // 说明解密后的明文数据类型的变量
		plainDatavalue = BytesToInt64(plainDataBytevalue[0:8]) // 将字节转换为对应的数据类型值
		plainDataInterface = plainDatavalue                    // 将明文结果值复制给接口
		return plainDataInterface, errMsg
		//plainDataTmp, errMsg := denseComputiing.PDecS64(encData, userAuthPW)
	case 3: //"uint64": // 64位无符号整数
		var plainDatavalue uint64                               // 说明解密后的明文数据类型的变量
		plainDatavalue = BytesToUint64(plainDataBytevalue[0:8]) // 将字节转换为对应的数据类型值
		plainDataInterface = plainDatavalue                     // 将明文结果值复制给接口
		return plainDataInterface, errMsg
		//plainDataTmp, errMsg := denseComputiing.PDec64(encData, userAuthPW)
	case 4: //"float32": // 32位浮点数
		var plainDatavalue float32                               // 说明解密后的明文数据类型的变量
		plainDatavalue = BytesToFloat32(plainDataBytevalue[4:8]) // 将字节转换为对应的数据类型值
		plainDataInterface = plainDatavalue                      // 将明文结果值复制给接口
		return plainDataInterface, errMsg
		//plainDataTmp, errMsg := denseComputiing.PDecF32(encData, userAuthPW)
	case 5: //"float64": // 64位浮点数
		var plainDatavalue float64                               // 说明解密后的明文数据类型的变量
		plainDatavalue = BytesToFloat64(plainDataBytevalue[0:8]) // 将字节转换为对应的数据类型值
		plainDataInterface = plainDatavalue                      // 将明文结果值复制给接口
		return plainDataInterface, errMsg
		//plainDataTmp, errMsg := denseComputiing.PDecF64(encData, userAuthPW)
	default:
		errMsg = errors.New("密文数据不对？")
	}
	return encData, errMsg
}

//// 将cgo的字节转换为c语言uchar
//func GetBytePointer(val []byte) *C.uchar {
//	return (*C.uchar)(unsafe.Pointer(&val[0]))
//}
//
//// 将字节转换为字符串
//func GetUcharPointer(val []byte) *C.uchar {
//	return (*C.uchar)(unsafe.Pointer(&val[0]))
//}

// 32位有符号整数转换成字节
func Int32ToBytes(n int) []byte {
	x := int32(n)
	bytesBuffer := bytes.NewBuffer([]byte{})
	binary.Write(bytesBuffer, binary.BigEndian, x)
	return bytesBuffer.Bytes()
}

// 32位无符号整数转换成字节
func Uint32ToBytes(n uint) []byte {
	x := uint32(n)
	bytesBuffer := bytes.NewBuffer([]byte{})
	binary.Write(bytesBuffer, binary.BigEndian, x)
	return bytesBuffer.Bytes()
}

// 64位有符号整数转换成字节
func Int64ToBytes(n int64) []byte {
	x := int64(n)
	bytesBuffer := bytes.NewBuffer([]byte{})
	binary.Write(bytesBuffer, binary.BigEndian, x)
	return bytesBuffer.Bytes()
}

// 64位无符号整数转换成字节
func Uint64ToBytes(n uint64) []byte {
	x := uint64(n)
	bytesBuffer := bytes.NewBuffer([]byte{})
	binary.Write(bytesBuffer, binary.BigEndian, x)
	return bytesBuffer.Bytes()
}

// 32位浮点数转换成字节
func Float32ToBytes(n float32) []byte {
	bytesBuffer := bytes.NewBuffer([]byte{})
	binary.Write(bytesBuffer, binary.BigEndian, n)
	return bytesBuffer.Bytes()
}

// 64位浮点数转换成字节
func Float64ToBytes(n float64) []byte {
	bytesBuffer := bytes.NewBuffer([]byte{})
	binary.Write(bytesBuffer, binary.BigEndian, n)
	return bytesBuffer.Bytes()
}

// 字节转换成8位有符号整数
func BytesToUnt8(b []byte) uint8 {
	bytesBuffer := bytes.NewBuffer(b)
	var x uint8
	binary.Read(bytesBuffer, binary.BigEndian, &x)
	return uint8(x)
}

// 字节转换成32位有符号整数
func BytesToInt32(b []byte) int32 {
	bytesBuffer := bytes.NewBuffer(b)
	var x int32
	binary.Read(bytesBuffer, binary.BigEndian, &x)
	return int32(x)
}

// 字节转换成32位无符号整数
func BytesToUint32(b []byte) uint32 {
	bytesBuffer := bytes.NewBuffer(b)
	var x uint32
	binary.Read(bytesBuffer, binary.BigEndian, &x)
	return uint32(x)
}

// 字节转换成64位有符号整数
func BytesToInt64(b []byte) int64 {
	bytesBuffer := bytes.NewBuffer(b)
	var x int64
	binary.Read(bytesBuffer, binary.BigEndian, &x)
	return int64(x)
}

// 字节转换成64位无符号整数
func BytesToUint64(b []byte) uint64 {
	bytesBuffer := bytes.NewBuffer(b)
	var x uint64
	binary.Read(bytesBuffer, binary.BigEndian, &x)
	return uint64(x)
}

// 字节转换成32位浮点数
func BytesToFloat32(b []byte) float32 {
	bytesBuffer := bytes.NewBuffer(b)
	var x float32
	binary.Read(bytesBuffer, binary.BigEndian, &x)

	return x
}

// 字节转换成64位浮点数
func BytesToFloat64(b []byte) float64 {
	bytesBuffer := bytes.NewBuffer(b)
	var x float64
	binary.Read(bytesBuffer, binary.BigEndian, &x)

	return x
}

//func GetUintPointeruint32(val []uint) *C.uint {
//	return (*C.uint)(unsafe.Pointer(&val[0]))
//}
